package com.yy.permissions_general.common.config;

import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import java.util.Properties;

@Configuration
public class TransactionConfig {

    /**
     * 全局事务位置配置 在哪些地方需要进行事务处理：具体如下
     * 配置切入点表达式,这里解释一下表达式的含义
     * 1.execution(): 表达式主体
     * 2.第一个*号:表示返回类型，*号表示所有的类型
     * 3.com.yy.permissions_general.service表示切入点的包名
     * 4.第二个*号:表示实现包
     * 5.*(..)*号表示所有方法名,..表示所有类型的参数
     */
    public static final String AOP_POINTCUT_EXPRESSION = "(execution(* com.yy.permissions_general.module.*.*.service.*.impl.*.*(..))) or (execution(* com.yy.permissions_general.module.*.*.service.*.*(..))) " +
            "or (execution(* com.yy.permissions_general.module.*.service.*.impl.*.*(..))) or (execution(* com.yy.permissions_general.module.*.service.*.*(..)))";

    @Bean
    @Primary //容器中存在多个相同类型bean，以此来标注首要选择
    public TransactionInterceptor txAdvice(PlatformTransactionManager platformTransactionManager) {
        TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
        // 事物管理器
        transactionInterceptor.setTransactionManager(platformTransactionManager);
        Properties attributes = new Properties();

        attributes.setProperty("insert*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("add*",      "PROPAGATION_REQUIRED");
        attributes.setProperty("update*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("edit*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("reset*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("del*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("stop*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("remove*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("submit*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("sync*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("return*",   "PROPAGATION_REQUIRED");
        attributes.setProperty("select*",   "PROPAGATION_REQUIRED,readOnly");
        attributes.setProperty("get*",  	"PROPAGATION_REQUIRED,readOnly");
        attributes.setProperty("query*",    "PROPAGATION_REQUIRED,readOnly");
        attributes.setProperty("find*",    "PROPAGATION_REQUIRED,readOnly");
        attributes.setProperty("list*",    "PROPAGATION_REQUIRED,readOnly");

        transactionInterceptor.setTransactionAttributes(attributes);
        return transactionInterceptor;
    }

    @Bean
    public AspectJExpressionPointcutAdvisor pointcutAdvisor(TransactionInterceptor txInterceptor){
        AspectJExpressionPointcutAdvisor pointcutAdvisor = new AspectJExpressionPointcutAdvisor();
        pointcutAdvisor.setAdvice(txInterceptor);
        pointcutAdvisor.setExpression(AOP_POINTCUT_EXPRESSION);
        return pointcutAdvisor;
    }
}
